#include "Setting.hpp"
#include <bb/system/Clipboard>
#include <QtCore/QObject>
#include <QTextCodec>
#include <QSettings>
#include <bb/device/DisplayInfo>
#include <bb/system/SystemToast>
#include <bb/PpsObject>
#include <bb/cascades/ThemeSupport>
#include <bb/cascades/Application>
#include <bb/cascades/VisualStyle>
#include <bb/cascades/Theme>
#include <bb/cascades/ColorTheme>
#include <bb/device/DisplayInfo>
#include <bb/system/Clipboard>
#include <bb/data/DataSource>
#include <QCryptographicHash>
#include <bb/data/JsonDataAccess>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkAccessManager>

using namespace bb::cascades;
using namespace bb::system;
using namespace bb::data;

namespace bb
{
    namespace cascades
    {
        class Application;
    }
}

const QString StyleKey = "STYLEKEY";
const QString ModeKey = "MODEKEY";
const QString PushInfo = "PUSHINFO";
const QString RegistInfo = "REGISTEINFO";

Setting::Setting(QObject *parent) :
        QObject(parent), m_invokeManager(new InvokeManager(this))
{
}
;

QString Setting::getValueFor(const QString objectName, const QString defaultValue)
{
    QSettings settings;

    if (settings.value(objectName).isNull()) {
        saveValueFor(objectName, defaultValue);
        return defaultValue;
    }

    return settings.value(objectName).toString();
}
;

void Setting::saveValueFor(const QString objectName, const QString inputValue)
{
    QSettings settings;
    settings.setValue(objectName, QVariant(inputValue));
}
;

void Setting::alert(QString info)
{
    SystemToast *toast = new SystemToast(this);
    toast->setBody(info);
    toast->setPosition(SystemUiPosition::MiddleCenter);
    toast->show();
}

void Setting::setVisualStyle(QString style)
{
    qDebug() << style;
    ThemeSupport *pThemeSupport = Application::instance()->themeSupport();
    qDebug() << pThemeSupport;

    Theme* pTheme = pThemeSupport->theme();
    ColorTheme* pColTheme = pTheme->colorTheme();

    qDebug() << pColTheme->style();
}

QString Setting::getStyle(const QString &defaultValue)
{
    return getValueFor(StyleKey, defaultValue);
}
;

void Setting::setStyle(const QString &inputValue)
{
    saveValueFor(StyleKey, inputValue);
}
;

QString Setting::getMode(const QString &defaultValue)
{
    return getValueFor(ModeKey, defaultValue);
}
;

void Setting::setMode(const QString &inputValue)
{
    saveValueFor(ModeKey, inputValue);
}
;

QString Setting::getPushInfo(const QString &defaultValue)
{
    return getValueFor(PushInfo, defaultValue);
}
;

void Setting::setPushInfo(const QString &inputValue)
{
    saveValueFor(PushInfo, inputValue);
}
;

QString Setting::getReg(const QString &defaultValue)
{
    return getValueFor(RegistInfo, defaultValue);
}
;

void Setting::setReg(const QString &inputValue)
{
    saveValueFor(RegistInfo, inputValue);
}
;

QString Setting::getEncrypt(const QString &input)
{
    QString result;
    QByteArray bs = qstringToByte(input);
    QString Key("Qo2ZRb1wIKCYeEDBMfjmapnhFA3lukXrPgqziUt0xTvNHWsVdcS89G7654JLOy");

    QString md5;
    QByteArray ba, bb;
    QCryptographicHash md(QCryptographicHash::Md5);
    ba.append(input + Key);
    md.addData(ba);
    bb = md.result();
    md5.append(bb.toHex());

    for (int i = 0; i < bs.size(); i++) {
        bs[i] = bs[i] ^ 7;
    }

    result = md5;
    qDebug() << result;
    return result;
}
;

QString Setting::byteToQString(const QByteArray &byte)
{
    QString result;
    if (byte.size() > 0) {
        QTextCodec *codec = QTextCodec::codecForName("utf-8");
        result = codec->toUnicode(byte);
    }

    return result;
}

QByteArray Setting::qstringToByte(const QString &strInfo)
{
    QByteArray result;
    if (strInfo.length() > 0) {
        QTextCodec *codec = QTextCodec::codecForName("utf-8");
        result = codec->fromUnicode(strInfo);
    }

    return result;
}

QVariantMap Setting::getDisplay()
{
    QVariantMap result;
    result["width"] = 0;
    result["height"] = 0;
    bb::device::DisplayInfo display;
    result["width"] = display.pixelSize().width();
    result["height"] = display.pixelSize().height();
    return result;
}
;

void Setting::CopyToClipBoard(const QString &input)
{
    bb::system::Clipboard clipboard;
    clipboard.clear();
    QByteArray byteData = qstringToByte(input);
    clipboard.insert("text/plain", byteData);
}
;

QString Setting::getToken()
{
    return "fe33252bdff2334b90c9c6d3f7e0fb36";
}
;

void Setting::SendEmail(const QString &email, const QString &title, const QString &body)
{
    InvokeRequest cardRequest;
    cardRequest.setTarget("sys.pim.uib.email.hybridcomposer");
    cardRequest.setAction("bb.action.SENDEMAIL");
    cardRequest.setMimeType("text/plain");
    //    cardRequest.setTargetTypes(bb::system::InvokeTarget::Application);
    cardRequest.setUri(tr("mailto:%1?title=%2&body=%3").arg(email).arg(title).arg(body));

    QVariantMap map;
    map.insert("title", title);
    map.insert("body", body);
    QByteArray requestData = bb::PpsObject::encode(map, NULL);
    cardRequest.setData(requestData);

    m_invokeManager->invoke(cardRequest);
}

void Setting::inVoke(QString target, QString action, QString mimetype, QString url, QString title)
{
    InvokeRequest cardRequest;
    cardRequest.setTarget(target);
    cardRequest.setAction(action);
    cardRequest.setMimeType(mimetype);
//    cardRequest.setTargetTypes(bb::system::InvokeTarget::Application);
    cardRequest.setUri(url);

    QVariantMap map;
    map.insert("contentTitle", title);
    map.insert("imageUri", "file:/" + QDir::currentPath() + "/app/native/assets/icon.png");
    QByteArray requestData = bb::PpsObject::encode(map, NULL);
    cardRequest.setData(requestData);

    m_invokeManager->invoke(cardRequest);
}
;

QString Setting::getCacheSize()
{
    QDir dir;
    QString dataDir(QDir::homePath());
    QString dirName = dataDir + "/cache/";
    dir.cd(dirName);
    quint64 sizex = dir_size(dirName);
    QString unit;
    if (sizex < 1024) {
        unit = "bytes";
    } else if (sizex < 1024 * 1024) {
        sizex /= 1024;
        unit = "kB";
    } else {
        sizex /= 1024 * 1024;
        unit = "MB";
    }

    emit cacheSizeChanged(QString::number(sizex) + unit);

    return QString::number(dir_size(dirName));
}

quint64 Setting::dir_size(const QString & str)
{
    quint64 sizex = 0;
    QFileInfo str_info(str);
    if (str_info.isDir()) {
        QDir dir(str);
        QFileInfoList list = dir.entryInfoList(
                QDir::Files | QDir::Dirs | QDir::Hidden | QDir::NoSymLinks | QDir::NoDotAndDotDot);
        for (int i = 0; i < list.size(); ++i) {
            QFileInfo fileInfo = list.at(i);
            if (fileInfo.isDir()) {
                sizex += dir_size(fileInfo.absoluteFilePath());
            } else
                sizex += fileInfo.size();
        }
    }

    return sizex;
}

void Setting::clearCache()
{
    QDir dir;
    QString dataDir(QDir::homePath());
    QString dirName = dataDir + "/cache/";
    dir.cd(dirName);

    QStringList list = dir.entryList();

    foreach (const QString &str, list){
        QFile theFile(dirName+str);
        qDebug()<<QFileInfo(dirName+str).size();
        theFile.remove();
        QFileInfo(theFile).size();
        qDebug()<<dirName+str;
    }

    SystemToast *toast = new SystemToast(this);
    toast->setBody("Cache cleared");
    toast->setPosition(SystemUiPosition::MiddleCenter);
    toast->show();
}


void Setting::RequestReg(){
//    QUrl url("http://api.iclient.ifeng.com/ClientNews?id=KJ123,FOCUSKJ123&page=1&random=0");
//
//    DataSource *ds = new DataSource();
//    ds->setSource(url);
//    QObject::connect(ds,SIGNAL(dataLoaded(const QVariant&)),this,SLOT(dataLoaded(const QVariant&)));
//    ds->load();
}

void Setting::dataLoaded(const QVariant &data){
    qDebug() << data;
//    QList<QVariant> list = data.toList();
//
//    QMap<QString, QVariant> map = list.first().toMap();
//    qDebug() << map["item"];
}


void Setting::VerifyReg(){

}
